#include "FuzeStdafx.h"
#include "stdafx.h"
#include <gtest/gtest.h>
#include "Register/BLR.h"
#include "SouthBridge/ICH.h"
#include "Bios/User.h"

class ICHTest : public testing::Test
{
public:
	ICHTest()
		:m_user()
	{
	}

	virtual void SetUp()
	{
	}

	virtual void TearDown()
	{
	}
	User m_user;
};

OrderInfo CreateOrder(double price, int quantity)
{
	OrderInfo order = {0};
	order.contractIndex = 0;
	order.direction = Direction::BUY;
	order.operation = Operation::OPEN;
	order.price = price;
	order.quantity = quantity;
	return order;
}

TEST_F(ICHTest, InsertTest)
{
	OrderInfo order = CreateOrder(1000, 10);
 	Dealing dealing(m_user, order);
	EXPECT_EQ(true, dealing.IsSend());

	dealing.OnSendFailed();
	EXPECT_TRUE(dealing.IsSendFailed());
	EXPECT_EQ(0, dealing.GetContractIndex());
	EXPECT_EQ(Direction::BUY, dealing.GetDirection());
	EXPECT_EQ(Operation::OPEN, dealing.GetOperation());
	EXPECT_DOUBLE_EQ(1000, dealing.GetOrderPrice());
	EXPECT_EQ(10, dealing.GetOrderQuantity());

	EXPECT_EQ(0, dealing.GetDealQuantity());
	EXPECT_EQ(10, dealing.GetRemainQuantity());
	EXPECT_EQ(0, dealing.GetCancelQuantity());

	string systemNo = "1234567";
	dealing.OnAccepted();
	EXPECT_FALSE(dealing.IsAccepted());

	dealing.OnOrdered(systemNo.c_str());
	EXPECT_TRUE(dealing.IsOrdered());
	EXPECT_EQ(systemNo,dealing.GetSystemNo());
	EXPECT_EQ(0, dealing.GetDealQuantity());
	EXPECT_EQ(10, dealing.GetRemainQuantity());
	EXPECT_EQ(0, dealing.GetCancelQuantity());
}

TEST_F(ICHTest, TradeImmediatelyTest)
{
	OrderInfo orderInfo = CreateOrder(1000.00, 10);
	Dealing dealing(m_user,orderInfo);
	string systemNo = "1234567";
	dealing.OnAccepted();

	dealing.OnOrdered(systemNo.c_str());
	Trade trade(dealing, 910.00, 10, systemNo.c_str());
	dealing.OnTrade(trade);
	EXPECT_TRUE(dealing.IsTrade());	
}

TEST_F(ICHTest, PartialAndCancelTest)
{
	OrderInfo order = CreateOrder(1000, 10);
	Dealing dealing(m_user, order);

	string systemNo = "1234567";
	dealing.OnAccepted();
	EXPECT_TRUE(dealing.IsAccepted());
	string sys = dealing.GetSystemNo();
	bool isEmpty = sys.empty();
	EXPECT_TRUE(isEmpty);
	dealing.OnOrdered(systemNo.c_str());

 	Trade trade(dealing, 990.8, 3, systemNo.c_str());
	dealing.OnTrade(trade);
	EXPECT_TRUE(dealing.IsPartial());
	EXPECT_EQ(trade.GetDealQuantity(), dealing.GetDealQuantity());
	EXPECT_DOUBLE_EQ(trade.GetDealPrice(), dealing.GetDealPrice());
	EXPECT_EQ(7, dealing.GetRemainQuantity());
	EXPECT_EQ(0, dealing.GetCancelQuantity());

	Trade trade2(dealing, 990.6, 5, systemNo.c_str());
	double expectedPrice = (990.8*3+990.6*5)/8;
	dealing.OnTrade(trade2);
	EXPECT_TRUE(dealing.IsPartial());
	EXPECT_EQ(8, dealing.GetDealQuantity());
	EXPECT_DOUBLE_EQ(expectedPrice, dealing.GetDealPrice());
	EXPECT_EQ(2, dealing.GetRemainQuantity());
	EXPECT_EQ(0, dealing.GetCancelQuantity());

	dealing.OnCancelFailed();
	EXPECT_TRUE(dealing.IsCancelFailed());
	EXPECT_EQ(8, dealing.GetDealQuantity());
	EXPECT_EQ(2, dealing.GetRemainQuantity());
	EXPECT_EQ(0, dealing.GetCancelQuantity());

	dealing.OnCanceled(8, 990.7);
	EXPECT_TRUE(dealing.IsCanceled());
	EXPECT_EQ(8, dealing.GetDealQuantity());
	EXPECT_EQ(0, dealing.GetRemainQuantity());
	EXPECT_EQ(2, dealing.GetCancelQuantity());
}
